package com.benew.ntt.xseval

import android.graphics.Color
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import com.benew.ntt.evaluate.EvalScore
import com.benew.ntt.evaluate.constant.EvalType
import com.benew.ntt.xseval.constant.XSEvalAction
import com.ntt.core.nlogger.NLogger
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject


object XSResultParse {
    val TAG = javaClass.simpleName


    /**
     * 获取句子结果
     */
    fun getResultText(
        resultStr: String?
    ): SpannableStringBuilder? {
        return getResultText(resultStr, null, null)
    }

    /**
     * 获取句子结果
     */
    fun getResultText(
        resultStr: String?,
        evalAction: String?,
        showText: String?
    ): SpannableStringBuilder? {
        if (resultStr == null) return null
        val spannableStringBuilder = SpannableStringBuilder()
        try {
            val jsonObject = JSONObject(resultStr)
            val result = jsonObject.optJSONObject("result")
            val requestCoreType = getRequestCoreType(jsonObject)
            val isCn = requestCoreType?.contains("cn.") //是否中文评测类型
            val details = result?.optJSONArray("details")
            if (details != null) {
                if ("cn.pred.score" == requestCoreType) { //古诗词类型或者段落类型，该类型外层包了snt_details
                    var detailItem: JSONObject?
                    var sntDetails: JSONArray?
                    for (i in 0 until details.length()) {
                        detailItem = details.getJSONObject(i)
                        if (detailItem != null) {
                            sntDetails = detailItem.getJSONArray("snt_details")
                            sntDetails?.let {
                                getChar(
                                    requestCoreType,
                                    it,
                                    spannableStringBuilder,
                                    true
                                )
                            }
                        }
                    }
                } else {
                    getChar(requestCoreType, details, spannableStringBuilder, isCn ?: false)
                }
                return insertPunctuation(
                    jsonObject,
                    spannableStringBuilder,
                    evalAction,
                    showText
                )
            }
        } catch (e: JSONException) {
            NLogger.e(
                TAG,
                "获取评测句子结果失败：" + e.message + ";resultStr=" + resultStr
            )
            e.printStackTrace()
        }
        return spannableStringBuilder
    }

    /**
     * 获取单个词
     */
    @Throws(JSONException::class)
    private fun getChar(
        requestCoreType: String?,
        jsonArray: JSONArray,
        spanBuilder: SpannableStringBuilder,
        isCn: Boolean
    ) {
        var jsonObject: JSONObject?
        var score: Int
        var start: Int
        val aChar =
            if (isCn && "cn.raw.score" != requestCoreType) "chn_char" else "char" //中文评测会返回chn_前缀
        val aScore =
            if (isCn && "cn.pred.score" != requestCoreType) "overall" else "score" //tonescore针对于音调的分数
        for (i in 0 until jsonArray.length()) {
            jsonObject = jsonArray.getJSONObject(i)
            if (jsonObject != null) {
                val charText = jsonObject.getString(aChar)
                score = jsonObject.getInt(aScore)
                start = spanBuilder.length
                if (!TextUtils.isEmpty(charText)) {
                    spanBuilder.append(charText)
                    when {
                        score >= EvalScore.STAR_FOUR -> {
                            setSan(spanBuilder, start, spanBuilder.length, "#74D95F")
                        }
                        score >= EvalScore.STAR_ONE -> {
                            setSan(spanBuilder, start, spanBuilder.length, "#FFB604")
                        }
                        else -> {
                            setSan(spanBuilder, start, spanBuilder.length, "#FF7040")
                        }
                    }
                }
            }
        }
    }

    /**
     * 插入标点符号
     *
     * @param jsonObject             评测结果
     * @param spanBuilder 评测结果文本
     */
    fun insertPunctuation(
        jsonObject: JSONObject?,
        spanBuilder: SpannableStringBuilder,
        evalAction: String?,
        showText: String?
    ): SpannableStringBuilder {
        var refText: String? = null
        return try {
            if (jsonObject != null) {
                try {
                    refText = jsonObject.getString("refText")
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            }
            var newRefText: String? = null
            if (!TextUtils.isEmpty(refText)) {
                newRefText = refText!!.replace("\\(.*?\\)|\\)|（.*?）|）".toRegex(), "") //去除所有括号内的内容
                val length = newRefText.length
                var resultLength: Int
                var c: Char
                var resultC = 0.toChar()
                for (i in 0 until length) {
                    c = newRefText[i]
                    resultLength = spanBuilder.length
                    if (i < resultLength) {
                        resultC = spanBuilder[i]
                    }

                    //先声会自动把中文的“’”替换成英文的“'”，所以插入原文本的字符
                    if (c != resultC && !('\'' == c && '’' == resultC) && !('\'' == resultC && '’' == c)) {
                        spanBuilder.insert(i, c.toString() + "")
                    }

                    //REPLACE这个action，替换掉显示字体
                    if (XSEvalAction.REPLACE.equals(
                            evalAction,
                            ignoreCase = true
                        ) && showText != null
                    ) {
                        spanBuilder.replace(i, i + 1, showText.subSequence(i, i + 1))
                    }

                }
            }
            NLogger.d(
                TAG,
                "插入标点符号",
                refText,
                newRefText,
                spanBuilder.toString()
            )
            spanBuilder
        } catch (e: Exception) {
            e.printStackTrace()
            val message = refText ?: ""
            NLogger.e(
                TAG,
                "插入标点符号发生异常" + e.message + ",refText=" + message,
            )
            SpannableStringBuilder(message) //插入异常返回原文本
        }
    }

    /**
     * 获取请求评测类型
     */
    private fun getRequestCoreType(jsonObject: JSONObject?): String? {
        try {
            val params = jsonObject?.optJSONObject("params")
            val request = params?.optJSONObject("request")
            return request?.getString("coreType")
        } catch (e: JSONException) {
            NLogger.e(
                TAG,
                "获取请求评测类型：" + e.message + ";jsonObject=" + jsonObject.toString()
            )
            e.printStackTrace()
        }
        return ""
    }

    /**
     * 设置样式
     */
    private fun setSan(text: SpannableStringBuilder, start: Int, end: Int, color: String) {
        text.setSpan(
            ForegroundColorSpan(
                Color.parseColor(color)
            ),
            start,
            end,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )
    }

    /**
     * 获取分数
     */
    fun getScore(resultStr: String?): Double {
        try {
            if (resultStr != null) {
                val jsonObject = JSONObject(resultStr)
                val result = jsonObject.optJSONObject("result")
                return result?.getDouble("overall") ?: 0.0
            }
        } catch (e: JSONException) {
            NLogger.e(TAG, "获取评测总分失败：$resultStr")
            e.printStackTrace()
        }
        return 0.0
    }
}